//
// Created by jack on 2021/2/1.
//

#ifndef WEILACSDK_WEILAPB_DEFINES_H
#define WEILACSDK_WEILAPB_DEFINES_H

#include <stddef.h>

#define PB_NULL 0
#define MAX_SHORTEST_STRING_LEN 8
#define MAX_PHONE_NUM_LEN 16
#define MAX_VERIFY_CODE_LEN 16
#define MAX_SHORT_STRING_LEN 64
#define MAX_M_SHORT_STRING_LEN 64
#define MAX_URL_STRING_LEN 128
#define MAX_NORMAL_STRING_LEN 256
#define MAX_LONG_STRING_LEN 2048

#define MAX_USER_CLIENT_COUNT 16

#define MAX_OWN_PTR_COUNT 12

#define PB_FALSE 0
#define PB_TRUE 1

#define ZERO_ARRAY_SIZE 4

typedef unsigned char  PB_BOOL;
typedef unsigned int   PB_UINT32;
typedef unsigned short PB_UINT16;
typedef unsigned char  PB_UINT8;
#ifdef WIN32
typedef _int64 PB_UINT64;
#else
typedef unsigned long long PB_UINT64;
#endif
typedef double PB_DOUBLE;
typedef float  PB_FLOAT;
typedef int    PB_INT32;
typedef short  PB_INT16;
typedef char   PB_CHAR;
#ifdef WIN32
typedef _int64 PB_INT64;
#else
typedef long long PB_INT64;
#endif

enum PB_ERROR_CODE {
    ERR_NONE              = 0,
    ERR_OUT_OF_MEMORY     = -1,
    ERR_INVALID_PARAMS    = -2,
    ERR_INVALID_RECV_DATA = -3,
    ERR_DECODE            = -4,
    ERR_ENCODE            = -5
};

enum PB_DATA_TYPE {
    PB_DATA_TYPE_DYNAMIC_STRING,     // 动态字符串
    PB_DATA_TYPE_FIXED_SIZE_STRING,  // 固定字符串
    PB_DATA_TYPE_ARRAY_INT32,        // INT32数组
    PB_DATA_TYPE_ARRAY_UINT32,       // UINT32数组
    PB_DATA_TYPE_ARRAY_INT64,        // INT64数组
    PB_DATA_TYPE_ARRAY_UINT64,       // UINT64数组
    PB_DATA_TYPE_ARRAY_FLOAT,        // FLOAT数组
    PB_DATA_TYPE_ARRAY_DOUBLE,       // DOUBLE数组
    PB_DATA_TYPE_ARRAY_SUBMSG,       // 子消息数组
    PB_DATA_TYPE_LINK_SUBMSG         // 子消息链表
};

typedef struct _PB_FUN_HOOK {
    void* (*allocMem)(size_t size);             // 申请内存
    void (*freeMem)(void* ptr);                 // 释放内存
    PB_UINT32 (*getTimeStamp)();                // 时间戳，UTC秒
    int (*weilaLog)(const char* pFormat, ...);  // trace
} PBFunHook;

// 全局错误码
typedef struct _PB_ERROR_INFO {
    PB_INT32 errCode;      // 错误码
    PB_CHAR  errMsg[256];  // 错误信息
} PBErrorInfo;

// 字串类型
typedef struct _PB_STRING {
    PB_INT32 strLen;
    PB_CHAR  str[ZERO_ARRAY_SIZE];
} PBString;

// 链表项
typedef struct _PB_LINK_ITEM {
    struct _PB_LINK_ITEM* pNext;
    PB_UINT32             dataSize;               // 链表项大小
    PB_UINT8              data[ZERO_ARRAY_SIZE];  // 链表项数据指针
} PBLinkItem;

// 链表
typedef struct _PB_LINK_LIST {
    PB_UINT32   listCount;  // 链表长度
    PBLinkItem* pLinks;     // 项
} PBLinkList;

///////////
// 微喇protocol收到网络数据并解析后得到的消息，以事件的方式回调，此结构
// 用来存储事件类型和事件内容。
enum PBEvntType {
    PB_EVT_MSG_RSP,          // 响应消息
    PB_EVT_MSG_IND,          // 通知消息
    PB_EVT_MSG_REQ,          // 请求消息
    PB_EVT_SESSION_MSG_IND,  // 会话消息通知类型
    PB_EVT_SYSTEM_ERR,       // 系统消息
};

// 微喇服务器的回调事件
typedef struct _PB_EVENT {
    PB_INT32 eventType;  // PBEvntType 枚举
    void*    pData;      // 数据
} PBEvent;

// 回调函数原型
typedef void (*PB_EVENT_LISTENER)(PBEvent* pEvent);
///////////

// 编码后的消息体，此数据结构用来承载需要发送到微喇服务器的消息
typedef struct _PB_ENC_RESULT {
    PB_INT32       errCode;
    const PB_CHAR* pErrMsg;
    PB_INT32 seq;  // 每一个消息都有一个唯一的序列号对应，为了后续可以对应服务器的响应信息
    PB_UINT32 message;          // 对应_PB_WEILA_MSG_TYPE
    PB_INT32  serviceId;        // 每一个消息都由一个服务id,告知消息属于什么范畴
    PB_INT32  commandId;        // 每一个消息都有一个命令id，告知消息属于范畴内的什么命令
    PB_INT32  encodedDataSize;  // 数据大小
    PB_UINT8* pEncodedData;     // 要发送到网络的数据（编码后的数据）
} PBEncResult;

// 用户状态
typedef struct _PB_USER_STATUS {
    PB_UINT16 statusType;        // 状态类型 0x01在线  0x02离线   0x03离开  0x04忙碌  0x05免打扰
    PB_UINT16 clientType;        // 设备类型
    PB_UINT32 updatedTimestamp;  // 时间戳 秒
} PBUserStatus;

enum _COMMAND_TYPE {
    WEILA_MSG_REQ = 0x00,  // 消息命令请求类型
    WEILA_MSG_RSP = 0x01,  // 消息命令响应类型
    WEILA_MSG_IND = 0x02   // 消息命令通知类型
};

enum _PB_WEILA_MSG_TYPE {
    WL_LOGIN_LOGIN_MSG,    // 对应的是PBRspLogin消息结构
    WL_LOGIN_LOGOUT_MSG,   // 没有响应结果数据，只有消息结果
    WL_LOGIN_KICKOUT_MSG,  // 对应的是PB_UINT32数据，代表被踢的原因 0 封号， 1 同一类型客户端同时登录 2 被移动端踢掉
    WL_LOGIN_HEARTBEAT_MSG,              // 没有响应结果数据，只有消息结果
    WL_LOGIN_REFRESH_ACCESS_TOKEN_MSG,   // 操作响应为MAX_SHORT_STRING_LEN长度的字符串缓存
    WL_LOGIN_ANSWER_BIND_EXTENSION_MSG,  // 对应PBRspAnswerBindExtension消息结构
    WL_LOGIN_BIND_EXTENSION_MSG,         // 通知对应PBNtfBindExtension， 响应只是返回消息结果
    WL_LOGIN_UNBIND_EXTENSION_MSG,       // 没有响应结果数据，只有消息结果
    WL_LOGIN_LOCK_EXTENSION,  // 通知设备状态 extensionState  0 未绑定， 1 绑定中， 2 已绑定， 3 上锁
    WL_LOGIN_UNLOCK_EXTENSION,  // 通知设备状态 extensionState  0 未绑定， 1 绑定中， 2 已绑定， 3 上锁
    WL_LOGIN_SET_EXTENSION_CONFIG_MSG,       // 操作响应无数据，只有成功结果，
                                             // 通知消息数据为MAX_LONG_STRING_LEN长度的字符串缓存
    WL_LOGIN_GET_EXTENSION_CONFIG_MSG,       // 操作响应为MAX_LONG_STRING_LEN长度的字符串缓存
    WL_LOGIN_SHUTDOWN_EXTENSION_MSG,         // 通知关机监护人Id
    WL_LOGIN_ANSWER_SHUTDOWN_EXTENSION_MSG,  // 操作响应无数据，只有成功结果

    WL_SESSION_MSGDATA_MSG,      // 通知为PBMsgData结构， 操作响应为PBSendMsgRsp
    WL_SESSION_GET_MSG_MSG,      // 操作响应为PBLinkList链表， 链表的具体数据为PBMsgData
    WL_SESSION_READ_MSG_MSG,     // 没有响应结果数据，只有消息结果
    WL_SESSION_GET_SESSION_MSG,  // 操作响应为PBGetSessionRsp数据， 里面的链表的具体数据为PBSessionInfo
    WL_SESSION_REMOVE_SESSION_MSG,  // 没有响应结果数据，只有消息结果
    WL_SESSION_GET_UNREAD_MSG_MSG,  // 操作响应为PBLinkList链表， 链表的具体数据为PBMsgData
    WL_SESSION_BURST_CTRL_MSG,  // 操作响应为PB_UINT32 duration， 持续时间， 通知消息为PBBurstCtlNtf数据
    WL_SESSION_MONITOR_CTRL_MSG,     // 没有响应结果数据， 通知消息为PBBurstCtlNtf数据
    WL_SESSION_EMBEDDED_ATTACH_MSG,  // 附着会话响应结果，无数据，只有结果
    WL_SESSION_VOIP_INVITE_MSG,      // VOIP邀请,通知消息为PBVoipInviteNtf
    WL_SESSION_VOIP_ACCEPT_MSG,      // VOIP接受,通知消息为PBVoipAcceptNtf
    WL_SESSION_VOIP_HANGUP_MSG,      // VOIP挂断,通知消息为PBVoipHangupNtf

    WL_GROUP_GET_GROUP_VER_MSG,   // 操作响应为PBLinkList链表，具体的数据为PBGroupSimpleInfo
    WL_GROUP_GET_GROUP_ATTR_MSG,  // 操作响应为PBLinkList链表，具体数据为PBGroupAttr
    WL_GROUP_CREATE_GROUP_MSG,    // 操作响应为PBCreateGroupRsp， 里面的链表数据为PBMemberInfo
    WL_GROUP_DEL_GROUP_MSG,  // 操作响应无数据，只有成功结果， 通知消息数据为PB_UINT64，代表群id
    WL_GROUP_DEL_MEMBER_MSG,            // 操作响应无数据，只有操作结果，通知消息为PBDelMemberNtf
    WL_GROUP_GET_MEMBER_USER_INFO_MSG,  // 操作响应为PBLinkList链表，具体数据为PBUserInfo
    WL_GROUP_GET_ONLINE_MEMBER_MSG,     // 操作响应为PBArray， 每一项为PB_UINT32
    WL_GROUP_CHANGE_GROUP_ATTR_MSG,  // 操作响应无数据，只有成功结果， 通知消息数据为PBGroupAttr
    WL_GROUP_GET_GROUP_INFO_MSG,     // 操作响应为PBGroupInfo
    WL_GROUP_GET_BLACKLIST_MSG,      // 操作响应为PBLinkList链表，具体数据为PBUserInfo
    WL_GROUP_CHANGE_BLACKLIST_MSG,   // 操作响应无数据，只有成功结果
    WL_GROUP_CHANGE_MEMBER_INFO_MSG,  // 操作响应无数据，只有成功结果， 通知消息数据为PBMemberChangeNtf
    WL_GROUP_ANSWER_GROUP_INVITE_MSG,  // 操作响应无数据，只有成功结果， 通知消息数据为PBAnswerGroupInviteNtf
    WL_GROUP_GROUP_JOIN_MSG,  // 操作响应无数据，只有成功结果， 通知消息数据为PBGroupJoinNtf
    WL_GROUP_ANSWER_GROUP_JOIN_MSG,  // 作响应无数据，只有成功结果， 通知消息数据为PBAnswerGroupJoinNtf
    WL_GROUP_BROADCAST_MSG,  // 作响应无数据，只有成功结果， 通知消息数据为PBLinkList, 数据项为PBBroadcastInfo
    WL_GROUP_GET_EMBEDDED_GROUP_VER_MSG,  // 作为获取嵌入式群信息的相应数据，操作响应为PBLinkList链表，具体的数据为PBGroupSimpleInfo
    WL_GROUP_GET_EMBEDDED_INFOS,  // 作为获取嵌入式群信息的相应数据，消息为PBLinkList，数据项为PBEmbeddedGroupInfo
    WL_GROUP_NEW_MEMBER_NTF_MSG,  // 群组新成员通知消息，对应的数据结构为PBNewMemberNtf

    WL_USER_CHANGE_USER_INFO_MSG,  // 作响应无数据，只有成功结果
    WL_USER_SET_CONFIG_MSG,  // 操作响应无数据，只有成功结果， 通知消息数据为MAX_LONG_STRING_LEN长度的字符串缓存
    WL_USER_GET_CONFIG_MSG,  // 操作响应为MAX_LONG_STRING_LEN长度的字符串缓存

    WL_LOCATION_REPORT_LOCATION_MSG,  // 作响应无数据，只有成功结果
    WL_LOCATION_GET_LOCATION_MSG,     // 操作响应为PBGetLocationRsp
    WL_LOCATION_LOCATION_CONTROL_MSG,  // 操作响应无数据，只有成功结果， 通知消息数据为PBLocationCtrlNtf
    WL_LOCATION_REPORT_TRACK_LOCATION_MSG,     // 作响应无数据，只有成功结果
    WL_LOCATION_REPORT_BUSINESS_LOCATION_MSG,  // 作响应无数据，只有成功结果

    WL_FRIEND_GET_FRIEND_INFO_MSG,  // 操作响应PBGetFriendInfoRsp, 其中有两个链表，对应PBUserInfo 和 对应PBFriendInfo
    WL_FRIEND_GET_FRIEND_USER_INFO_MSG,  // 操作响应为PBLinkList链表，具体数据为PBUserInfo
    WL_FRIEND_GET_FRIEND_INVITE_INFO_MSG,  // 操作响应PBGetFriendInviteInfoRsp,其中有两个链表，对应PBUserInfo 和
                                           // 对应PBFriendInfo
    WL_FRIEND_FRIEND_INVITE_MSG,  // 操作响应无数据，只有成功结果， 通知消息数据为PBAnswerFriendInviteNtf
    WL_FRIEND_ANSWER_FRIEND_INVITE_MSG,  // 操作响应无数据，只有成功结果， 通知消息数据为PBAnswerFriendInviteNtf
    WL_FRIEND_NEW_FRIEND_MSG,  // 通知消息数据为PBFriendInfo
    WL_FRIEND_DELETE_FRIEND_MSG,  // 操作响应无数据，只有成功结果， 通知消息数据为PB_UINT32 代表用户id
    WL_FRIEND_CHANGE_FRIEND_INFO_MSG,     // 操作响应无数据，只有成功结果
    WL_FRIEND_GET_BLACKLIST_MSG,          // 操作响应为PBLinkList链表，具体数据为PBUserInfo
    WL_FRIEND_CHANGE_BLACKLIST_MSG,       // 操作响应无数据，只有成功结果
    WL_FRIEND_GET_ONLINE_FRIEND_MSG,      // 操作响应为PBArray， 每一项为PB_UINT32
    WL_FRIEND_GET_EMBEDDED_FRIEND_INFOS,  // 操作响应为PBLinkList链表，具体数据为PBFriendEmbeddedInfo
    WL_SYSTEM_NOTIFICATION_MSG,           // 操作响应为PBString

    WL_ERROR_MSG,
};

///////////////////////////////
// 内部使用，不需要理会
enum _PB_RECYCLE_PTR_TYPE {
    RECYCLE_PTR_LINK = 1,
    RECYCLE_PTR_MSGDATA_LINK,
};

typedef struct _PB_RESERVED_DATA {
    PB_UINT32 pointerType;
    void*     pPtr;
} PBRecyclePtr;
//////////////////////////////

// 此数据结构是微喇收到服务器响应消息或通知消息或请求消息后，会转化
// 为此数据结构的消息。用户可以依据message类型，通过pContent指向
// 对应的数据结构来获取数据。一般情况下，请先判断resultCode是否为0，
// 如果是非0，则pContent一般情况下不需要理会
typedef struct _PB_WEILA_MSG {
    ////////////////////////////
    // 内部使用，不需要理会
    PB_UINT32    recyclePtrCount;
    PBRecyclePtr recyclePtrData[10];
    //////////////////////

    PB_UINT16 message;      // 枚举类型_PB_WEILA_MSG_TYPE
    PB_UINT16 serviceId;    // 服务号id，可以不用理会
    PB_UINT16 commandId;    // 命令id，可以不用理会
    PB_UINT16 commandType;  // 命令类型，可以不用理会
    PB_UINT16 resultCode;   // 消息错误码，为0代表正确
    PB_UINT32 contentSize;  // 消息内容的大小
    PB_UINT32
    seqNum;  // 序列号，每发一个消息，都会生成此序号，以此来对应是哪个消息的响应（如果是通知消息类型，一般为0）
    PB_UINT8 pContent[ZERO_ARRAY_SIZE];  // 内容指针， 具体内容参考枚举类型_PB_WEILA_MSG_TYPE的注释，指向此内容的指针
} PBWeilaMsg;

// 用户信息结构体
typedef struct _PB_USER_INFO {
    PB_UINT32 userId;            // 用户id
    PB_UINT32 sex;               // 用户性别
    PB_INT32  status;            // 状态
    PB_UINT32 type;              // 用户类型 0 普通用户 1 设备用户 2 企业用户
    PB_UINT32 createdTimestamp;  // 创建时间

    PB_CHAR number[MAX_PHONE_NUM_LEN];   // 微喇号
    PB_CHAR nick[MAX_SHORT_STRING_LEN];  // 昵称
    PB_CHAR avatar[MAX_URL_STRING_LEN];  // 头像

    PB_CHAR email[MAX_URL_STRING_LEN];             // email
    PB_CHAR phone[MAX_PHONE_NUM_LEN];              // 电话
    PB_CHAR countryCode[MAX_SHORTEST_STRING_LEN];  // 国家码
    PB_CHAR signature[MAX_NORMAL_STRING_LEN];      // 签名
} PBUserInfo;

typedef struct _PB_REQ_LOGIN_LIGHT {
    PB_UINT32 sizeOfStruct;
    PB_BOOL   passwordWithMD5;                 // 密码是否已经经过MD5加密
    PB_CHAR   account[MAX_PHONE_NUM_LEN];      // 账号，是手机号或微喇号
    PB_CHAR   password[MAX_SHORT_STRING_LEN];  // 密码，长度尽量不要超过32个字节，否则报错
    PB_CHAR   countryCode
        [MAX_SHORTEST_STRING_LEN];  // 国家码，如果是手机号登录，则填对应的国家码，如86。如果是微喇号登录，填0
    PB_UINT32 userConfigVersion;  // 用户配置版本号，可以填0
} PBReqLoginParam;

typedef struct _PB_REQ_LOGIN_FULL {
    PBReqLoginParam baseParam;
    PB_CHAR appId[MAX_PHONE_NUM_LEN];      // 所有SDK登录均需要appID，此appID不同开发者不一样，必填
    PB_CHAR appKey[MAX_SHORT_STRING_LEN];  // 所有SDK登录均需要appKey，此appKey不同开发者不一样，必填
    PB_CHAR
    deviceSpecial[MAX_NORMAL_STRING_LEN];  // 设备相关信息,必须按照 {"id":"xxx","imei":"xxx","product":"meizu_M5s"}
                                           // 此格式的Json字串，必填
    PB_CHAR deviceInfo[MAX_URL_STRING_LEN];  // 设备额外信息，可以不填
} PBReqLoginExtParam;

// 登录响应消息
typedef struct _PB_RSP_LOGIN {
    PBUserInfo userInfo;                // 携带的用户信息
    PBLinkList userStatusList;          // 在对应设备上的状态
    PB_UINT32  clientCount;             // 在多少个设备上登录
    PB_UINT32  forbiddenDuration;       // 被禁时间
    PB_UINT32  extensionState;          // 扩展设备状态
    PB_UINT32  embeddedMaxAttachCount;  // 允许附着最大群
    PB_CHAR    userConfig[MAX_LONG_STRING_LEN];
    PB_CHAR token[MAX_M_SHORT_STRING_LEN];  // 令牌，后续上传文字转语音，AAC和PTT互换等API接口需要用到
    PB_CHAR   verificationCode[MAX_VERIFY_CODE_LEN];  // 验证码
    PB_CHAR   extAccount[MAX_PHONE_NUM_LEN];          // 绑定的账号
    PB_CHAR   extPass[MAX_SHORT_STRING_LEN];          // 绑定账号的密码
    PB_UINT32 extManagerId;                           // 绑定管理员
    PB_UINT32 extensionType;
    PB_CHAR   extensionConfig[MAX_LONG_STRING_LEN];
    PB_UINT32 timestamp;
} PBRspLogin;

// 设备绑定通知，APP需要绑定设备的时候，会发送此通知给设备
typedef struct _PB_NTF_BIND_EXTENSION {
    PB_UINT32 binderId;                          // 设备id
    PB_CHAR   binderNick[MAX_SHORT_STRING_LEN];  // 设备昵称
} PBNtfBindExtension;

// 绑定的应答响应
typedef struct _PB_RSP_ANSWER_BIND_EXTENSION {
    PB_UINT32 extensionState;                  // 设备状态
    PB_CHAR   account[MAX_PHONE_NUM_LEN];      // 账号
    PB_CHAR   password[MAX_SHORT_STRING_LEN];  // 密码MD5
} PBRspAnswerBindExtension;

typedef struct _PB_ARRAY_DATA {
    PB_UINT16 arrayType;  // 数组元素类型， 枚举
    PB_UINT16 listCount;
    PB_UINT8  data[ZERO_ARRAY_SIZE];
} PBArray;

// 文件信息，包括文件名，文件网址和文件大小
typedef struct _PB_FILE_INFO {
    PB_CHAR   fileName[MAX_SHORT_STRING_LEN];
    PB_CHAR   fileIcon[MAX_URL_STRING_LEN];
    PB_CHAR   fileUrl[MAX_URL_STRING_LEN];
    PB_UINT32 fileSize;
} PBFileInfo;

// 用户位置消息
typedef struct _PB_LOCATION_INFO_SHARED {
    PB_FLOAT latitude;                               // 纬度
    PB_FLOAT longitude;                              // 经度
    PB_CHAR  locationType[MAX_SHORTEST_STRING_LEN];  // 定位类型
    PB_CHAR  locationName[MAX_SHORT_STRING_LEN];     // 名字
    PB_CHAR  locationAddr[MAX_NORMAL_STRING_LEN];    // 位置地址
    PB_CHAR  locationMapUrl[MAX_URL_STRING_LEN];     // 地图url
} PBLocationInfoShared;

// 音频结构，可以作为数据和URL合用
typedef struct _PB_AUDIO {
    PB_UINT16 audioType;  // IM_AUDIO_DATA_TYPE 或 IM_AUDIO_URL_TYPE
    PB_UINT16 audioSize;  // 数据大小或URL字符串大小
    PB_UINT8  audioData[ZERO_ARRAY_SIZE];
} PBAudio;

typedef struct _PB_BURST_DATA {
    PB_UINT64   sessionId;    // 会话Id
    PB_UINT16   sessionType;  // 会话类型
    PB_UINT32   senderId;     // 发送者Id
    PB_UINT32   sourceType;   // 语音源类型
    PB_UINT32   burstSeq;     // 语音序号
    PB_UINT32   packetSeq;    // 语音片段序号
    PB_BOOL     isMonitor;    // 是否监听
    PB_BOOL     isVoip;       // 是否VOIP
    PB_UINT32   marker;       // burst 标记 0 首包 1 中间包 2 结束包 3 整段
    PBLinkList* pFrameList;   // 帧链表，每一个项都是一个opus的20ms的数据和大小
} PBBurstData;

////// 消息相关
enum WeilaMsgType {
    IM_TEXT_MSG_TYPE,       // 文字信息 直接对应字符串
    IM_FILE_INFO_TYPE,      // 文件信息 对应PBFileInfo
    IM_IMAGE_INFO_TYPE,     // 图片信息 直接对应字符串
    IM_VIDEO_INFO_TYPE,     // 视频信息 对应PBFileInfo
    IM_LOCATION_INFO_TYPE,  // 位置信息 对应PBLocationInfoShared
    IM_COMMAND_TYPE,        // 命令信息 对应字符串
    IM_AUDIO_DATA_TYPE,     // 音频数据 对应PBAudio
    IM_AUDIO_URL_TYPE,      // 音频URL 对应字符串
    IM_PTT_DATA_TYPE,       // PTT语音 对应PBPtt
    IM_VOIP_DATA_TYPE,      // VOIP语音 对应PBPtt
    IM_SWITCH_DATA_TYPE,    // 直通数据 对应PB_UINT8数据
    IM_SERVICE_TYPE,        // 服务型数据 对应字符串
    IM_UNKNOWN_TYPE         // 未知
};

// 消息数据
typedef struct _PB_MSG_DATA {
    PB_UINT32 onlineCount;                       // 群的在线人数
    PB_UINT32 senderId;                          // 发送者id
    PB_CHAR   senderName[MAX_SHORT_STRING_LEN];  // 发送者昵称
    PB_UINT64
    sessionId;  // 会话id，一般个人会话对应的是对方的用户id，群会话对应的是群id，服务会话对应的是（服务id|用户id）
    PB_UINT16 sessionType;               // 会话类型 1个人， 2群， 8服务
    PB_UINT32 msgId;                     // 消息id
    PB_UINT16 msgType;                   // 消息类型，对应枚举WeilaMsgType
    PB_UINT16 autoReply;                 // 是否自动应答
    PB_UINT32 created;                   // 创建时间戳，秒
    PB_UINT32 contentSize;               // 内容大小
    PB_UINT8  content[ZERO_ARRAY_SIZE];  // 依据不同的类型有对应不同的数据类型
} PBMsgData;

// 发送消息响应
typedef struct _PB_SEND_MSG_RSP {
    PB_UINT32 msgId;
    PB_UINT64 createdTimestamp;
    PB_UINT32 remoteOffline;  // 0在线 1不在线(单呼有效)
    PB_UINT32 onlineCount;    // 在线成员(大于0有效)
} PBSendMsgRsp;

typedef struct _PB_SESSION_INFO {
    PB_UINT64 sessionId;
    PB_UINT32 sessionType;
    PB_UINT32 readMsgId;
} PBSessionInfo;

typedef struct _PB_GET_SESSION_RSP {
    PB_UINT64  latestUpdated;
    PBLinkList sessionList;
} PBGetSessionRsp;

typedef struct _PB_BURST_CTRL_NTF {
    PB_UINT64 sessionId;
    PB_UINT16 sessionType;
    PB_UINT16 burstType;
    PB_UINT32 talkerId;
} PBBurstCtlNtf;

typedef struct _PB_MONITOR_CTRL_NTF {
    PB_UINT32 monitorId;  // 监听用户Id
    PB_UINT16 status;     // 0 关闭 1 开启
    PB_UINT16 duration;   // 监听持续时长
} PBMonitorCtlNtf;

// PTT DATA的帧位置
enum _PTT_DATA_FRAME { FIRST_PTT_FRAME = 0x00, MIDDLE_PTT_FRAME = 0x01, END_PTT_FRAME = 0x02 };

// ptt结构
typedef struct _PB_PTT {
    PB_UINT16 marker;  // ptt标识, 0x00 语音首包, 0x01 语音中间包, 0x02 语音分段包, 0x03 语音结束, 0xff 丢弃
    PB_UINT16 seq;  // 语音序号, 一段语音可能分成多个段，每个段又分成多个包。这个是段序号
    PB_UINT16  packageSeq;  // 段内的分包，每个包都有序号
    PB_UINT16  source;
    PB_UINT32  frameCount;
    PBLinkList frameList;  // 主要是opus的数据, 20ms的数据封装
} PBPtt;

typedef struct _PB_GROUP_EMBEDDED_INFO {
    PB_UINT64 groupId;                     // 群组Id
    PB_UINT32 version;                     // 群组版本号
    PB_CHAR   name[MAX_SHORT_STRING_LEN];  // 群组名
    PB_CHAR   number[MAX_PHONE_NUM_LEN];   // 群号
    PB_UINT32 ownerId;                     // 群主id
    PB_UINT16 type;                        // 群类型
    PB_UINT16 burstType;                   // 对讲模式 0 排对， 1 抢话筒， 2 打断
    PB_UINT16 speechPermission;            // 禁言状态 0不禁言， 1禁言
    PB_UINT16 memberCount;                 // 群成员数
    PB_UINT16 recvStatus;                  // 自己所在群理自己的接收状态 0 不屏蔽 1 屏蔽消息
    PB_UINT16 tts;                         // 自己所在群的文字转语音模式 0 关闭 1开启
    PB_UINT16 sharedLocation;              // 自己所在群的自己共享状态 0 不共享 1共享
    PB_UINT16 memberType;                  // 自己所在群，自己所属成员类型
    PB_UINT16 priority;                    // 自己所在群，自己的话权优先级
    PB_UINT16 selfSpeechPermission;        // 自己所在群自己的被禁言状态 0 不屏蔽 1 屏蔽消息
    PB_UINT32 memberVersion;               // 群成员版本号
    PB_UINT64 shutupTimeout;               // 自己被禁言超时时间
} PBEmbeddedGroupInfo;

typedef struct _PB_GROUP_ATTR {
    PB_UINT64 groupId;                     // 群id
    PB_CHAR   name[MAX_SHORT_STRING_LEN];  // 群名字
    PB_CHAR   number[MAX_PHONE_NUM_LEN];   // 群号
    PB_CHAR   avatar[MAX_URL_STRING_LEN];  // 群头像
    PB_CHAR   desc[MAX_LONG_STRING_LEN];   // 群描述
    PB_UINT32 ownerId;                     // 群主id
    PB_UINT16 groupType;                   // 群类型 1正式， 0临时
    PB_UINT16 publicType;                  // 是否公开 1不公开， 2公开
    PB_UINT16 speechPermission;            // 禁言状态 0不禁言， 1禁言
    PB_UINT16 memberVersion;               // 群成员版本号
    PB_UINT16 authType;  // 认证与否 1不鉴权 2管理员确认 3管理员确认或密码验证 4管理员确认以及密码验证
    PB_UINT16 burstType;         // 对讲模式 0 排对， 1 抢话筒， 2 打断
    PB_UINT32 memberCount;       // 成员数目
    PB_UINT64 createdTimestamp;  // 群创建时间戳 秒
} PBGroupAttr;

typedef struct _PB_CHANGE_GROUP_ATTR {
    PB_BOOL   changeName;        // 是否改名
    PB_BOOL   changeAvatar;      // 是否改头像
    PB_BOOL   changeDesc;        // 是否改描述
    PB_BOOL   changeOwnerId;     // 是否转让群主
    PB_BOOL   changeGroupType;   // 是否改群类型
    PB_BOOL   changePublicType;  // 是否改群公开
    PB_BOOL   changeAuthType;    // 是否改群认证方式
    PB_BOOL   changeBurstType;   // 是否改群话筒模式
    PB_CHAR   name[MAX_SHORT_STRING_LEN];
    PB_CHAR   avatar[MAX_URL_STRING_LEN];
    PB_CHAR   desc[MAX_LONG_STRING_LEN];
    PB_CHAR   authPassword[MAX_NORMAL_STRING_LEN];
    PB_UINT32 ownerId;
    PB_UINT16 groupType;
    PB_UINT16 publicType;
    PB_UINT16 authType;
    PB_UINT16 burstType;
} PBChangeGroupAttr;

typedef struct _PB_CHANGE_MEMBER_INFO {
    PB_BOOL changeType;
    PB_BOOL changeRemark;
    PB_BOOL changePriority;
    PB_BOOL changeSpeechPermission;
    PB_BOOL changeRecvStatus;
    PB_BOOL changeTTSStatus;
    PB_BOOL changeSharedLocationStatus;

    PB_UINT16 memberType;                     // 成员类型1普通， 2管理员
    PB_UINT16 priority;                       // 优先级
    PB_UINT16 speechPermission;               // 禁言状态 0 不禁， 1禁
    PB_UINT16 recvStatus;                     // 消息接受状态 0 不接收， 1接收
    PB_UINT16 ttsStatus;                      // 文字转语音开关 0 关闭， 1打开
    PB_UINT16 sharedLocationStatus;           // 位置分享开关 0 关， 1开
    PB_UINT64 slientDuration;                 // 禁言持续时长
    PB_CHAR   remark[MAX_NORMAL_STRING_LEN];  // 备注
} PBChangeMemberInfo;

typedef struct _PB_MEMBER_INFO {
    PB_UINT32 userId;
    PB_CHAR   remark[MAX_NORMAL_STRING_LEN];
    PB_UINT16 status;
    PB_UINT16 priority;
    PB_UINT16 speechPermission;
    PB_UINT32 silentDuration;
    PB_UINT16 recvStatus;
    PB_UINT16 tts;
    PB_UINT16 sharedLocation;
    PB_UINT16 memberType;
} PBMemberInfo;

typedef struct _PB_GROUP_SIMPLE_INFO {
    PB_UINT64 groupId;
    PB_UINT32 groupVersion;
    PB_UINT32 memberVersion;
} PBGroupSimpleInfo;

typedef PBLinkList PBGetGroupVersionRsp;
typedef PBLinkList PBGetGroupAttrRsp;
typedef PBLinkList PBGetGroupBlackListRsp;
typedef PBLinkList PBGetMemberUserInfoRsp;
typedef PBLinkList PBChangeMemberInfoNtf;
typedef PBLinkList PBBroadcastNtf;
typedef PBLinkList PBGetLocationRsp;
typedef PBLinkList PBGetFriendUserInfoRsp;
typedef PBLinkList PBGetFriendBlacklistRsp;
typedef PBLinkList PBGetEmbeddedGroupInfoRsp;

typedef struct _PB_CREATE_GROUP_RSP {
    PBGroupAttr groupAttr;
    PBLinkList  memberInfoList;
} PBCreateGroupRsp;

typedef struct _PB_NEW_MEMBER_NTF {
    PB_UINT64 groupId;
    PB_UINT32 inviterId;
} PBNewMemberNtf;

typedef struct _PB_GROUP_INFO {
    PBGroupAttr groupAttr;
    PBLinkList  memberInfoList;
    PB_UINT32   partial;
} PBGroupInfo;

typedef struct _PB_ONLINE_MEMBER {
    PB_UINT32  listCount;
    PB_UINT32* pUserList;
} PBOnlineMember;

typedef struct _PB_DEL_MEMBER_NTF {
    PB_UINT64 groupId;
    PB_UINT32 operatorId;
    PBArray   userList;
} PBDelMemberNtf;

typedef struct _PB_MEMBER_INFO_CHANGE_NTF {
    PB_UINT64    groupId;
    PBMemberInfo memberInfo;
} PBMemberChangeNtf;

typedef struct _PB_ANSWER_GROUP_INVITE_NTF {
    PB_UINT64 groupId;
    PB_UINT32 inviterId;  // 邀请者id
    PB_UINT32 inviteeId;  // 被邀请者id
    PB_UINT32 status;     // 应答状态 1 接收， 2 拒绝， 3忽略
    PB_UINT32 createdTimestamp;
} PBAnswerGroupInviteNtf;

typedef struct _PB_GROUP_JOIN_NTF {
    PB_UINT64  groupId;
    PB_UINT32  joinId;                         // 申请加入者id
    PB_CHAR    detail[MAX_NORMAL_STRING_LEN];  // 原因
    PBUserInfo userInfo;                       // 加入者用户信息
} PBGroupJoinNtf;

typedef struct _PB_ANSWER_GROUP_JOIN_NTF {
    PB_UINT64 groupId;
    PB_UINT32 joinId;
    PB_UINT32 answerId;
    PB_UINT32 status;
    PB_UINT32 createdTimestamp;
} PBAnswerGroupJoinNtf;

typedef struct _PB_BROADCAST_INFO {
    PB_UINT64 groupId;
    PB_UINT32 broadcastId;
    PB_UINT32 status;
} PBBroadcastInfo;

typedef struct _PB_CHANGE_USER_INFO {
    PB_BOOL changeSex;
    PB_BOOL changeNick;
    PB_BOOL changeAvatar;
    PB_BOOL changeSignature;

    PB_UINT32 sex;
    PB_CHAR   nick[MAX_SHORT_STRING_LEN];
    PB_CHAR   avatar[MAX_URL_STRING_LEN];
    PB_CHAR   signature[MAX_NORMAL_STRING_LEN];
} PBChangeUserInfo;

typedef struct _PB_LOCATION_INFO {
    PB_UINT32 userId;
    PB_UINT16 clientType;
    PB_UINT16 locationType;
    PB_DOUBLE latitude;
    PB_DOUBLE longitude;
    PB_DOUBLE speed;
    PB_DOUBLE altitude;
    PB_DOUBLE radius;
    PB_DOUBLE direction;
    PB_UINT32 timestamp;
} PBLocationInfo;

typedef struct _PB_LOCATION_EXTA_INFO {
    PB_CHAR   appId[MAX_SHORT_STRING_LEN];
    PB_UINT32 extensionType;                   // 扩展信息类型
    PB_CHAR   extension[MAX_LONG_STRING_LEN];  // 扩展类型
} PBLocationExtraInfo;

typedef struct _PB_LOCATION_CTRL_NTF {
    PB_UINT64 sessionId;
    PB_UINT16 sessionType;
    PB_BOOL   status;     // 开关
    PB_UINT16 frequency;  // 上报频率
    PB_UINT16 duration;   // 持续时间
} PBLocationCtrlNtf;

typedef struct _PB_CHANGE_FRIEND_INFO {
    PB_BOOL changeRemark;
    PB_BOOL changeLabel;
    PB_BOOL changeRecvStatus;
    PB_BOOL changeTts;
    PB_BOOL changeLocationShared;

    PB_CHAR   remark[MAX_NORMAL_STRING_LEN];
    PB_CHAR   label[MAX_SHORT_STRING_LEN];
    PB_UINT16 recvStatus;
    PB_UINT16 Tts;
    PB_UINT16 locationShared;
} PBChangeFriendInfo;

typedef struct _PB_FRIEND_EMBDDED_INFO {
    PB_UINT32 userId;
    PB_CHAR   number[MAX_PHONE_NUM_LEN];   // 微喇号
    PB_CHAR   nick[MAX_SHORT_STRING_LEN];  // 昵称
    PB_UINT16 status;                      // 好友状态 0 正常 1 删除
    PB_UINT16 sex;                         // 用户性别
    PB_UINT16 tts;                         // 状态
    PB_UINT16 locationShared;              // 位置分享开关
    PB_UINT16 recvStatus;                  // 是否接收
} PBFriendEmbeddedInfo;

typedef struct _PB_FIREND_INFO {
    PB_UINT32 userId;
    PB_UINT16 status;
    PB_UINT16 recvStatus;      // 是否接收
    PB_UINT16 tts;             // 文字转语音开关
    PB_UINT16 locationShared;  // 位置分享开关

    PB_CHAR remark[MAX_NORMAL_STRING_LEN];
    PB_CHAR label[MAX_SHORT_STRING_LEN];
    PB_CHAR desc[MAX_LONG_STRING_LEN];
    PB_CHAR extension[MAX_NORMAL_STRING_LEN];
} PBFriendInfo;

typedef struct _PB_GET_FRIEND_INFO_RSP {
    PB_UINT64  latestTimestamp;
    PBLinkList friendInfoList;
    PBLinkList userInfoList;
} PBGetFriendInfoRsp;

typedef struct _PB_FRIEND_INVITE_INFO {
    PB_UINT32 inviterId;
    PB_UINT32 inviteeId;
    PB_UINT32 status;
    PB_CHAR   detail[MAX_NORMAL_STRING_LEN];
    PB_UINT64 timestamp;
} PBFriendInviteInfo;

typedef struct _PB_GET_FRIEND_INVITE_INFO_RSP {
    PB_UINT64  latestUpdated;
    PBLinkList friendInfoList;
    PBLinkList userInfoList;
} PBGetFriendInviteInfoRsp;

typedef PBGetFriendInviteInfoRsp PBFriendInviteNtf;

typedef struct _PB_ANSWER_FRIEND_INVITE_NTF {
    PB_UINT32 inviteeId;
    PB_UINT32 status;
} PBAnswerFriendInviteNtf;

typedef struct _PB_VOIP_INVITE_RSP {
    PBUserInfo userInfo;  // 被邀请者用户信息
} PBVoipInviteRsp;

typedef struct _PB_VOIP_INVITE_NTF {
    PB_CHAR    callId[MAX_NORMAL_STRING_LEN];
    PB_UINT32  userId;
    PBUserInfo userInfo;  // 邀请者用户信息
} PBVoipInviteNtf;

typedef struct _PB_VOIP_ACCEPT_NTF {
    PB_CHAR    callId[MAX_NORMAL_STRING_LEN];
    PB_UINT32  userId;
    PBUserInfo userInfo;  // 被邀请者用户信息
} PBVoipAcceptNtf;

typedef struct _PB_VOIP_HANGUP_NTF {
    PB_CHAR   callId[MAX_NORMAL_STRING_LEN];
    PB_UINT32 userId;
} PBVoipHangupNtf;

typedef struct _PB_GET_EMBEDDED_FRIEND_INFO_RSP {
    PB_UINT64  latestUpdated;
    PBLinkList friendInfoList;
} PBGetEmbeddedFriendInfoRsp;

#endif  // WEILACSDK_WEILAPB_DEFINES_H
